package config

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/joho/godotenv"
	"gopkg.in/yaml.v3"
)

// Config 应用程序配置结构
type Config struct {
	Database DatabaseConfig `yaml:"database" json:"database"`
	Server   ServerConfig   `yaml:"server" json:"server"`
	Logging  LoggingConfig  `yaml:"logging" json:"logging"`
	Security SecurityConfig `yaml:"security" json:"security"`
}

// DatabaseConfig Oracle数据库配置
type DatabaseConfig struct {
	Host            string        `yaml:"host" json:"host" env:"DB_HOST"`
	Port            int           `yaml:"port" json:"port" env:"DB_PORT"`
	Username        string        `yaml:"user" json:"user" env:"DB_USER"`
	Password        string        `yaml:"password" json:"password" env:"DB_PASSWORD"`
	ServiceName     string        `yaml:"service_name" json:"service_name" env:"DB_SERVICE_NAME"`
	SID             string        `yaml:"sid" json:"sid" env:"DB_SID"`
	ConnectString   string        `yaml:"connect_string" json:"connect_string" env:"DB_CONNECT_STRING"`
	MaxOpenConns    int           `yaml:"max_open_conns" json:"max_open_conns" env:"DB_MAX_OPEN_CONNS"`
	MaxIdleConns    int           `yaml:"max_idle_conns" json:"max_idle_conns" env:"DB_MAX_IDLE_CONNS"`
	ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime" json:"conn_max_lifetime" env:"DB_CONN_MAX_LIFETIME"`
	ConnMaxIdleTime time.Duration `yaml:"conn_max_idle_time" json:"conn_max_idle_time" env:"DB_CONN_MAX_IDLE_TIME"`
}

// ServerConfig 服务器配置
type ServerConfig struct {
	Mode string `yaml:"mode" json:"mode"` // stdio, http, websocket
	Host string `yaml:"host" json:"host"`
	Port int    `yaml:"port" json:"port"`
}

// LoggingConfig 日志配置
type LoggingConfig struct {
	Level  string `yaml:"level" json:"level"`
	Format string `yaml:"format" json:"format"` // json, text
}

// SecurityConfig 安全策略配置
type SecurityConfig struct {
	EnableSafetyCheck bool          `yaml:"enable_safety_check" json:"enable_safety_check"`
	MaxQueryLimit     int           `yaml:"max_query_limit" json:"max_query_limit"`
	QueryTimeout      time.Duration `yaml:"query_timeout" json:"query_timeout"`
}

// Load 加载配置
// 优先级：环境变量 > YAML配置文件 > .env文件 > 默认值
func Load(configPath string) (*Config, error) {
	// 创建默认配置
	config := &Config{
		Database: DatabaseConfig{
			Host:            "localhost",
			Port:            1521,
			Username:        "system",
			Password:        "",
			ServiceName:     "XE",
			SID:             "",
			ConnectString:   "",
			MaxOpenConns:    25,
			MaxIdleConns:    25,
			ConnMaxLifetime: 5 * time.Minute,
			ConnMaxIdleTime: 5 * time.Minute,
		},
		Server: ServerConfig{
			Mode: "stdio",
			Host: "localhost",
			Port: 8080,
		},
		Logging: LoggingConfig{
			Level:  "info",
			Format: "text",
		},
		Security: SecurityConfig{
			EnableSafetyCheck: true,
			MaxQueryLimit:     10000,
			QueryTimeout:      30 * time.Second,
		},
	}

	// 如果指定了配置文件路径，尝试加载配置文件
	if configPath != "" {
		// 检查文件扩展名，决定加载方式
		if strings.HasSuffix(configPath, ".yaml") || strings.HasSuffix(configPath, ".yml") {
			// 加载YAML配置文件
			data, err := os.ReadFile(configPath)
			if err != nil {
				return nil, fmt.Errorf("读取YAML配置文件失败: %w", err)
			}
			if err := yaml.Unmarshal(data, config); err != nil {
				return nil, fmt.Errorf("解析YAML配置文件失败: %w", err)
			}
		} else {
			// 加载.env文件
			if err := godotenv.Load(configPath); err != nil {
				return nil, fmt.Errorf("加载.env配置文件失败: %w", err)
			}
		}
	} else {
		// 尝试加载默认的配置文件
		// 优先尝试config.yaml，然后是.env
		if _, err := os.Stat("config.yaml"); err == nil {
			data, err := os.ReadFile("config.yaml")
			if err == nil {
				_ = yaml.Unmarshal(data, config)
			}
		} else if _, err := os.Stat(".env"); err == nil {
			_ = godotenv.Load()
		}
	}

	// 环境变量覆盖配置文件设置
	if host := os.Getenv("DB_HOST"); host != "" {
		config.Database.Host = host
	}
	if port := os.Getenv("DB_PORT"); port != "" {
		if p, err := strconv.Atoi(port); err == nil {
			config.Database.Port = p
		}
	}
	if username := os.Getenv("DB_USER"); username != "" {
		config.Database.Username = username
	}
	if password := os.Getenv("DB_PASSWORD"); password != "" {
		config.Database.Password = password
	}
	if serviceName := os.Getenv("DB_SERVICE_NAME"); serviceName != "" {
		config.Database.ServiceName = serviceName
	}
	if sid := os.Getenv("DB_SID"); sid != "" {
		config.Database.SID = sid
	}
	if maxOpen := os.Getenv("DB_MAX_OPEN_CONNS"); maxOpen != "" {
		if m, err := strconv.Atoi(maxOpen); err == nil {
			config.Database.MaxOpenConns = m
		}
	}
	if maxIdle := os.Getenv("DB_MAX_IDLE_CONNS"); maxIdle != "" {
		if m, err := strconv.Atoi(maxIdle); err == nil {
			config.Database.MaxIdleConns = m
		}
	}
	if maxLifetime := os.Getenv("DB_CONN_MAX_LIFETIME"); maxLifetime != "" {
		if d, err := time.ParseDuration(maxLifetime); err == nil {
			config.Database.ConnMaxLifetime = d
		}
	}
	if maxIdleTime := os.Getenv("DB_CONN_MAX_IDLE_TIME"); maxIdleTime != "" {
		if d, err := time.ParseDuration(maxIdleTime); err == nil {
			config.Database.ConnMaxIdleTime = d
		}
	}

	if mode := os.Getenv("SERVER_MODE"); mode != "" {
		config.Server.Mode = mode
	}
	if host := os.Getenv("SERVER_HOST"); host != "" {
		config.Server.Host = host
	}
	if port := os.Getenv("SERVER_PORT"); port != "" {
		if p, err := strconv.Atoi(port); err == nil {
			config.Server.Port = p
		}
	}

	if level := os.Getenv("LOG_LEVEL"); level != "" {
		config.Logging.Level = level
	}
	if format := os.Getenv("LOG_FORMAT"); format != "" {
		config.Logging.Format = format
	}

	return config, nil
}